using System;
using System.Collections.Generic;

namespace SmartSite.Frame
{
    public class ULongField : Field<ulong>, IValueField<ulong>
    {
        const int MaxCount = 64;
        public ulong MaxValue { get => Count.ULongMask(); }
#pragma warning disable CA1822
        public ulong MinValue { get => 0; }
#pragma warning restore

        readonly ValueOperating<ulong> ValueOperating;

        public ULongField(List<byte> buffer, BitUnit index, int count)
        : base(buffer, index, count)
        {
            ValueOperating = CreateValueOperating();
        }

        public ULongField(IBytesBuffer buffer, BitUnit index, int count)
        : base(buffer, index, count)
        {
            ValueOperating = CreateValueOperating();
        }

        public ULongField(IField field, int count)
        : base(field, count)
        {
            ValueOperating = CreateValueOperating();
        }

        public ULongField(IField field)
        : base(field, MaxCount)
        {
            ValueOperating = CreateValueOperating();
        }

        ValueOperating<ulong> CreateValueOperating()
        {
            return new ValueOperating<ulong>(
                BitsVariable,
                Count,
                () => 0UL,
                (a) => (byte)a,
                (a, count) => a << count,
                (a, count) => a >> count,
                (a, b) => a + b
            );
        }
        public override ulong Value
        {
            get
            {
                ValueOperating.RestoreBits(out ulong result);
                return result;
            }

            set
            {
                if (value < MinValue || value > MaxValue)
                    throw new ArgumentOutOfRangeException(nameof(value));

                ValueOperating.ToByteList(value, out List<byte> bits).CopyToBitsVariable(bits);
            }
        }
    }
}
